package com.kidala.tool;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Map.Entry;

/**
 * Tool sluzacy do znajdywania nieuzywanych propertisow zdefiniowanych w pliku
 * properties w obrebie wskazanego folderu i plikow o zadanej masce
 *
 * @author Luck
 */
public class UnusedPropertyFinder {

    /**
     * Start programu
     *
     * @param args
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void main(String[] args) throws FileNotFoundException, IOException {
        UnusedPropertyFinder luncher = new UnusedPropertyFinder();
        //luncher.findUnusedProperties(
        //        "d:/workspace_jsf/VCMS2_trunk_bgz/src/main/java/com/visiona/vcms/res/lang/UI.properties",
        //        "d:/workspace_jsf/VCMS2_trunk_bgz/src/main/webapp/", "xhtml");
        luncher.findUnusedProperties(
                "d:/workspace_jsf/VCMS2_trunk_bgz/src/main/java/com/visiona/vcms/res/lang/MessageResources.properties",
                "d:/workspace_jsf/VCMS2_trunk_bgz/src/main/java/", "java");
    }

    private int fileNumber;
    private List<String> forRemove = new LinkedList<String>();

    /**
     * Wyszukuje nieuzywane klucze propertisow
     *
     * @param propertiesFileName
     * @param folderForCheck
     * @param checkFileMask
     * @throws FileNotFoundException
     * @throws IOException
     */
    public void findUnusedProperties(String propertiesFileName, String folderForCheck, String... checkFileMask)
            throws FileNotFoundException, IOException {
        Properties properties = loadProperties(propertiesFileName);
        Iterator<Entry<Object, Object>> iterator = properties.entrySet().iterator();
        for (int i = 0; iterator.hasNext(); i++) {
            Entry<Object, Object> next = iterator.next();
            String key = (String) next.getKey();
            System.out.println("Checking property " + key + "...");
            fileNumber = 0;
            boolean isUsed = checkProperty(key, new File(folderForCheck), checkFileMask);
            if (isUsed) {
                System.out.println(i + " Is used");
            } else {
                System.out.println(i + " Is not used");
                forRemove.add(key.toString() + "=" + next.getValue());
            }
        }
        System.out.println("==========================================================");
        System.out.println("Properties list for remove: ");
        Collections.sort(forRemove);
        for (String prop : forRemove) {
            System.out.println(prop);
        }
    }

    /**
     * Sprawdza dany property
     *
     * @param key
     * @param file
     * @param checkFileMask
     * @return
     * @throws IOException
     */
    private boolean checkProperty(String key, File file, String... checkFileMask) throws IOException {
        if (file.isDirectory()) {
            /*
             * System.out.println("Searching for the key: " + key +
             * " in directory: " + file.getAbsolutePath());
             */
            File[] listFiles = file.listFiles();
            for (File subFile : listFiles) {
                boolean checkProperty = checkProperty(key, subFile, checkFileMask);
                if (checkProperty) {
                    return true;
                }
            }
            return false;
        } else {
            boolean fitToMask = false;
            for (String mask : checkFileMask) {
                if (file.getName().endsWith(mask)) {
                    fitToMask = true;
                    break;
                }
            }
            if (!fitToMask) {
                return false;
            }

            fileNumber++;
            /*
             * System.out.println(fileNumber + " Searching for the key: " + key
             * + " in file: " + file.getName());
             */
            return findKeyInFile(key, file);
        }
    }

    /**
     * Szuka wskazanego klucza w danym pliku
     *
     * @param key
     * @param file
     * @return
     * @throws IOException
     */
    private boolean findKeyInFile(String key, File file) throws IOException {
        InputStreamReader inStream = new FileReader(file);
        BufferedReader in = null;
        try {
            in = new BufferedReader(inStream);
            String str;
            while ((str = in.readLine()) != null) {
                boolean contains = str.contains(key);
                if (contains) {
                    return true;
                }
            }
        } finally {
            in.close();
        }
        return false;
    }

    /**
     * Laduje plik propertisow
     *
     * @param propertiesFileName
     * @return
     * @throws FileNotFoundException
     * @throws IOException
     */
    private Properties loadProperties(String propertiesFileName) throws FileNotFoundException, IOException {
        InputStream inStream = null;
        try {
            inStream = new FileInputStream(new File(propertiesFileName));
            Properties properties = new Properties();
            properties.load(inStream);
            return properties;
        } finally {
            inStream.close();
        }
    }

}
